package com.storyroad.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.json.JSONObject;

import com.storyroad.responseClasses.Profile;
import com.storyroad.responseClasses.StoryView;
import com.storyroad.utils.DBConnection;
import com.storyroad.utils.TableNames;
import com.storyroad.utils.Utilities;

/**
 * Servlet implementation class GetProfile
 */
public class GetProfile extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public GetProfile() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * Gets the necessary information to display on the profile page of a registered user. An instance of
	 * {@link com.storyroad.responseClasses.Profile} which contains user contents and user data is returned to
	 * the front-end.
	 * @param request HttpServletRequest object that contains data coming from front-end
	 * @param response HttpServletResponse object that contains data which is prepared after processing the incoming data
	 * @throws ServletException
	 * @throws IOException
	 */
	protected void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String f_requestType = request.getParameter("request_type");
		String f_username = "";
		String f_targetUsername = "";
		if (f_requestType == null || !f_requestType.equals("Android")) {
			f_requestType = "Web";
			if (request.getParameter("targetname") == null) {
				f_targetUsername = (String) request.getSession().getAttribute("username");
				if (f_targetUsername == null) {
					// Check whether this action is performed by a registered user. If not, the user is redirected to the login page.
					response.sendRedirect(response.encodeRedirectURL(request.getContextPath() + "/LoginPage.jsp"));
					return;
				}
			} else {
				f_targetUsername = (String) request.getParameter("targetname");
			}
			f_username = (String) request.getSession().getAttribute("username");

		} else {
			f_username = (String) request.getParameter("username");
			f_targetUsername = (String) request.getParameter("targetname");
		}

		Connection conn = new DBConnection().connect();
		PrintWriter out = response.getWriter();
		if (conn == null) {
			out.println("Connection error");
		} else {
			try {
				request.setCharacterEncoding("utf8");
				response.setContentType("application/json");
				boolean isFollowing = false;
				PreparedStatement stmt = conn.prepareStatement("SELECT u_id, email, photoLink FROM " + TableNames.USERS_TABLE
								+ " WHERE username = ?");
				stmt.setString(1, f_targetUsername);
				ResultSet rs = stmt.executeQuery();
				String email = null;
				String photoLink = null;
				int u_id = -1;
				if (rs.next()) {
					email = rs.getString("email");
					u_id = rs.getInt("u_id");
					photoLink = rs.getString("photoLink");
				}

				int followerCount = getFollowerCount(conn, u_id);

				Profile profile = new Profile(f_targetUsername, email, photoLink, followerCount);

				stmt = conn.prepareStatement("SELECT Story.s_id,title,(totalRating / ratingCount) AS avgRating FROM "
								+ TableNames.STORIES_TABLE
								+ " WHERE Story.owner = ?");
				stmt.setInt(1, u_id);
				ResultSet rs2 = stmt.executeQuery();
				while (rs2.next()) {
					int s_id = rs2.getInt("s_id");
					String title = rs2.getString("title");
					String tags = Utilities.getTags(conn, s_id);
					double avgRating = rs2.getDouble("avgRating");
					profile.addStoryToStoriesArray(new StoryView(s_id, title,tags, avgRating));
				}

				// Follow check.
				int cu_id = -1;
				if (!f_targetUsername.equals(f_username)) {
					cu_id = Utilities.getUserId(conn, f_username);
					stmt = conn.prepareStatement("SELECT * FROM "
							+ TableNames.FOLLOW_TABLE
							+ " WHERE follower_id = ? AND followed_id = ?");
					stmt.setInt(1, cu_id);
					stmt.setInt(2, u_id);
					ResultSet rs4 = stmt.executeQuery();
					if (rs4.next()) {
						isFollowing = true;
					}
				}
				profile.setFollowing(isFollowing);
				if (f_requestType.equals("Android")) {
					JSONObject jsonObjectFromProfileObject = new JSONObject(
							profile);
					String storyObjectToBeReturned = jsonObjectFromProfileObject
							.toString();
					out.print(storyObjectToBeReturned);
				} else if (f_requestType.equals("Web")) {
					// After the operation is completed, redirect to the profile page
					request.setAttribute("profileObject", profile);
					request.getRequestDispatcher("ProfilePage.jsp").forward(request, response);

				}
			} catch (SQLException e) {
				out.print(e.getMessage());
				e.printStackTrace();
			}
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * Finds the number of people who follow this user
	 * @param conn connection object to communicate with the database
	 * @param userId ID of the user
	 * @return number of people that follows this user
	 */
	private int getFollowerCount(Connection conn, int userId) {

		int result = 0;
		ResultSet rs;
		PreparedStatement stmt;

		try {
			stmt = conn.prepareStatement("SELECT COUNT(*) AS total FROM "
					+ TableNames.FOLLOW_TABLE + " WHERE followed_id = ?");
			stmt.setInt(1, userId);
			rs = stmt.executeQuery();
			if (rs.next()) {
				result = rs.getInt("total");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return result;
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		processRequest(request, response);
	}

}
